/*     */ package com.zimbra.cs.index.query.parser;
/*     */ 
/*     */ import com.google.common.base.Objects;
/*     */ import com.google.common.base.Strings;
/*     */ import com.google.common.collect.ImmutableMap;
/*     */ import com.google.common.collect.ImmutableMap.Builder;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.index.query.AddrQuery;
/*     */ import com.zimbra.cs.index.query.AddrQuery.Address;
/*     */ import com.zimbra.cs.index.query.AttachmentQuery;
/*     */ import com.zimbra.cs.index.query.BuiltInQuery;
/*     */ import com.zimbra.cs.index.query.ConjQuery;
/*     */ import com.zimbra.cs.index.query.ConjQuery.Conjunction;
/*     */ import com.zimbra.cs.index.query.ContactQuery;
/*     */ import com.zimbra.cs.index.query.ConvCountQuery;
/*     */ import com.zimbra.cs.index.query.ConvQuery;
/*     */ import com.zimbra.cs.index.query.DateQuery;
/*     */ import com.zimbra.cs.index.query.DateQuery.Type;
/*     */ import com.zimbra.cs.index.query.DomainQuery;
/*     */ import com.zimbra.cs.index.query.FieldQuery;
/*     */ import com.zimbra.cs.index.query.HasQuery;
/*     */ import com.zimbra.cs.index.query.InQuery;
/*     */ import com.zimbra.cs.index.query.InQuery.In;
/*     */ import com.zimbra.cs.index.query.ItemQuery;
/*     */ import com.zimbra.cs.index.query.ModseqQuery;
/*     */ import com.zimbra.cs.index.query.PriorityQuery;
/*     */ import com.zimbra.cs.index.query.PriorityQuery.Priority;
/*     */ import com.zimbra.cs.index.query.Query;
/*     */ import com.zimbra.cs.index.query.Query.Modifier;
/*     */ import com.zimbra.cs.index.query.SenderQuery;
/*     */ import com.zimbra.cs.index.query.SizeQuery;
/*     */ import com.zimbra.cs.index.query.SizeQuery.Type;
/*     */ import com.zimbra.cs.index.query.SubQuery;
/*     */ import com.zimbra.cs.index.query.SubjectQuery;
/*     */ import com.zimbra.cs.index.query.TagQuery;
/*     */ import com.zimbra.cs.index.query.TextQuery;
/*     */ import com.zimbra.cs.index.query.TypeQuery;
/*     */ import com.zimbra.cs.mailbox.MailItem.Type;
/*     */ import com.zimbra.cs.mailbox.MailServiceException;
/*     */ import com.zimbra.cs.mailbox.Mailbox;
/*     */ import com.zimbra.cs.service.util.ItemId;
/*     */ import java.io.StringReader;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collections;
/*     */ import java.util.EnumSet;
/*     */ import java.util.LinkedList;
/*     */ import java.util.List;
/*     */ import java.util.Locale;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import java.util.TimeZone;
/*     */ import java.util.regex.Matcher;
/*     */ import java.util.regex.Pattern;
/*     */ import org.apache.lucene.analysis.Analyzer;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public final class QueryParser
/*     */ {
/*     */   private static final Map<String, Integer> IMG2JJ;
/*     */   
/*     */   static
/*     */   {
/* 155 */     ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
/* 156 */     for (int i = 0; i < ParserConstants.tokenImage.length; i++) {
/* 157 */       String token = ParserConstants.tokenImage[i];
/* 158 */       if ((token.startsWith("\"")) || (token.endsWith(":\""))) {
/* 159 */         builder.put(token.substring(1, token.length() - 1), Integer.valueOf(i));
/*     */       }
/*     */     }
/* 162 */     IMG2JJ = builder.build();
/*     */   }
/*     */   
/* 165 */   private static final Map<String, Integer> FOLDER2ID = new ImmutableMap.Builder().put("inbox", Integer.valueOf(2)).put("trash", Integer.valueOf(3)).put("junk", Integer.valueOf(4)).put("sent", Integer.valueOf(5)).put("drafts", Integer.valueOf(6)).put("contacts", Integer.valueOf(7)).build();
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 174 */   private static final Map<Integer, String> JJ2LUCENE = new ImmutableMap.Builder().put(Integer.valueOf(21), "l.contactData").put(Integer.valueOf(16), "l.content").put(Integer.valueOf(18), "msg_id").put(Integer.valueOf(20), "env_from").put(Integer.valueOf(19), "env_to").put(Integer.valueOf(23), "from").put(Integer.valueOf(22), "to").put(Integer.valueOf(24), "cc").put(Integer.valueOf(17), "subject").put(Integer.valueOf(31), "filename").put(Integer.valueOf(68), "type").put(Integer.valueOf(69), "attachment").put(Integer.valueOf(40), "l.field").put(Integer.valueOf(29), "IN").put(Integer.valueOf(67), "HAS").put(Integer.valueOf(64), "IS").put(Integer.valueOf(43), "DATE").put(Integer.valueOf(49), "AFTER").put(Integer.valueOf(50), "BEFORE").put(Integer.valueOf(51), "APPT-START").put(Integer.valueOf(52), "APPT-END").put(Integer.valueOf(55), "SIZE").put(Integer.valueOf(56), "BIGGER").put(Integer.valueOf(57), "SMALLER").put(Integer.valueOf(32), "TAG").put(Integer.valueOf(34), "MY").put(Integer.valueOf(33), "MESSAGE").put(Integer.valueOf(58), "CONV").put(Integer.valueOf(59), "CONV-COUNT").put(Integer.valueOf(60), "CONV_MINM").put(Integer.valueOf(61), "CONV_MAXM").put(Integer.valueOf(53), "CONV-START").put(Integer.valueOf(54), "CONV-END").put(Integer.valueOf(35), "AUTHOR").put(Integer.valueOf(36), "TITLE").put(Integer.valueOf(37), "KEYWORDS").put(Integer.valueOf(38), "COMPANY").put(Integer.valueOf(39), "METADATA").put(Integer.valueOf(70), "ITEMID").build();
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 216 */   private static Pattern FIELD_REGEX = Pattern.compile("field\\[(.+)\\]:|#(.+):", 2);
/*     */   
/*     */   private final Mailbox mailbox;
/*     */   private final Analyzer analyzer;
/* 220 */   private TimeZone timezone = TimeZone.getTimeZone("UTC");
/* 221 */   private Locale locale = Locale.ENGLISH;
/* 222 */   private int defaultField = 16;
/*     */   private String sortBy;
/* 224 */   private Set<MailItem.Type> types = EnumSet.noneOf(MailItem.Type.class);
/* 225 */   private boolean quick = false;
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public QueryParser(Mailbox mbox, Analyzer analyzer)
/*     */   {
/* 234 */     this.mailbox = mbox;
/* 235 */     this.analyzer = analyzer;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void setTimeZone(TimeZone value)
/*     */   {
/* 244 */     this.timezone = value;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void setLocale(Locale value)
/*     */   {
/* 253 */     this.locale = value;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public void setDefaultField(String name)
/*     */     throws ServiceException
/*     */   {
/* 263 */     Integer jj = (Integer)IMG2JJ.get(name);
/* 264 */     if (jj == null) {
/* 265 */       throw MailServiceException.QUERY_PARSE_ERROR(name, null, name, -1, "UNKNOWN_QUERY_TYPE");
/*     */     }
/* 267 */     this.defaultField = jj.intValue();
/*     */   }
/*     */   
/*     */   public void setTypes(Set<MailItem.Type> value) {
/* 271 */     this.types = value;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public String getSortBy()
/*     */   {
/* 282 */     return this.sortBy;
/*     */   }
/*     */   
/*     */   public void setQuick(boolean value) {
/* 286 */     this.quick = value;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public List<Query> parse(String src)
/*     */     throws ServiceException
/*     */   {
/* 297 */     if (Strings.isNullOrEmpty(src)) {
/* 298 */       throw MailServiceException.QUERY_PARSE_ERROR(src, null, "", 0, "Empty query string not allowed");
/*     */     }
/* 300 */     Parser parser = new Parser(new StringReader(src));
/*     */     try {
/* 302 */       SimpleNode node = parser.parse();
/* 303 */       assert (node.id == 0);
/* 304 */       assert (node.jjtGetNumChildren() == 1);
/* 305 */       return toQuery((SimpleNode)node.jjtGetChild(0));
/*     */     } catch (TokenMgrError e) {
/* 307 */       if (this.quick) {
/* 308 */         return Collections.singletonList(createQuickQuery(src));
/*     */       }
/* 310 */       throw MailServiceException.QUERY_PARSE_ERROR(src, e, "", -1, e.getMessage());
/*     */     }
/*     */     catch (ParseException e) {
/* 313 */       if (this.quick) {
/* 314 */         return Collections.singletonList(createQuickQuery(src));
/*     */       }
/* 316 */       throw MailServiceException.QUERY_PARSE_ERROR(src, e, e.currentToken.image, e.currentToken.beginColumn, e.getMessage());
/*     */     }
/*     */   }
/*     */   
/*     */   private List<Query> toQuery(SimpleNode node)
/*     */     throws ParseException, ServiceException
/*     */   {
/* 323 */     assert (node.id == 1);
/*     */     
/* 325 */     List<Query> result = new LinkedList();
/* 326 */     ConjQuery conj = null;
/* 327 */     for (int i = 0; i < node.jjtGetNumChildren(); i++) {
/* 328 */       SimpleNode child = (SimpleNode)node.jjtGetChild(i);
/* 329 */       switch (child.id) {
/*     */       case 8: 
/* 331 */         conj = toConjunction(child);
/* 332 */         break;
/*     */       case 2: 
/* 334 */         if (!result.isEmpty()) {
/* 335 */           if (conj == null) {
/* 336 */             result.add(new ConjQuery(ConjQuery.Conjunction.AND));
/*     */           } else {
/* 338 */             result.add(conj);
/* 339 */             conj = null;
/*     */           }
/*     */         }
/* 342 */         result.add(toClause(child));
/* 343 */         break;
/*     */       case 11: 
/* 345 */         processSortBy(child);
/* 346 */         break;
/*     */       default: 
/* 348 */         if (!$assertionsDisabled) throw new AssertionError();
/*     */         break; }
/*     */     }
/* 351 */     return result;
/*     */   }
/*     */   
/*     */   private Query toClause(SimpleNode node) throws ParseException, ServiceException {
/* 355 */     assert (node.id == 2);
/* 356 */     int num = node.jjtGetNumChildren();
/* 357 */     assert ((num > 0) && (num <= 2));
/*     */     
/* 359 */     Query clause = null;
/* 360 */     SimpleNode child = (SimpleNode)node.jjtGetChild(num - 1);
/* 361 */     switch (child.id) {
/*     */     case 4: 
/* 363 */       clause = toTextClause(child);
/* 364 */       break;
/*     */     case 5: 
/* 366 */       clause = toItemClause(child);
/* 367 */       break;
/*     */     case 6: 
/* 369 */       clause = toDateClause(child);
/* 370 */       break;
/*     */     case 1: 
/* 372 */       clause = toSubQuery(child);
/* 373 */       break;
/*     */     case 3: 
/* 375 */       if ((this.quick) && (node.jjtGetFirstToken().beginColumn == 1)) {
/* 376 */         throw new ParseException("quick mode");
/*     */       }
/* 378 */       clause = toDefaultClause(child);
/* 379 */       break;
/*     */     case 2: default: 
/* 381 */       if (!$assertionsDisabled) throw new AssertionError();
/* 382 */       return null;
/*     */     }
/* 384 */     if (node.jjtGetNumChildren() > 1) {
/* 385 */       clause.setModifier(toModifier((SimpleNode)node.jjtGetChild(0)));
/*     */     }
/* 387 */     return clause;
/*     */   }
/*     */   
/*     */   private Query toSubQuery(SimpleNode node) throws ParseException, ServiceException {
/* 391 */     assert (node.id == 1);
/* 392 */     return new SubQuery(toQuery(node));
/*     */   }
/*     */   
/*     */   private Query toTextClause(SimpleNode node) throws ParseException, ServiceException {
/* 396 */     assert (node.id == 4);
/* 397 */     assert (node.jjtGetNumChildren() == 1);
/*     */     
/* 399 */     return toTerm(node.jjtGetFirstToken(), (SimpleNode)node.jjtGetChild(0));
/*     */   }
/*     */   
/*     */   private Query toDefaultClause(SimpleNode node) throws ParseException, ServiceException {
/* 403 */     assert (node.id == 3);
/*     */     
/* 405 */     return createQuery(Token.newToken(this.defaultField), node.jjtGetFirstToken(), toString(node));
/*     */   }
/*     */   
/*     */   private Query toItemClause(SimpleNode node) throws ParseException, ServiceException {
/* 409 */     assert (node.id == 5);
/* 410 */     assert (node.jjtGetNumChildren() == 1);
/*     */     
/* 412 */     return toTerm(node.jjtGetFirstToken(), (SimpleNode)node.jjtGetChild(0));
/*     */   }
/*     */   
/*     */   private Query toDateClause(SimpleNode node) throws ParseException, ServiceException {
/* 416 */     assert (node.id == 6);
/* 417 */     assert (node.jjtGetNumChildren() == 1);
/*     */     
/* 419 */     return toTerm(node.jjtGetFirstToken(), (SimpleNode)node.jjtGetChild(0));
/*     */   }
/*     */   
/*     */   private Query toTerm(Token field, SimpleNode node) throws ParseException, ServiceException {
/* 423 */     assert ((node.id == 14) || (node.id == 12) || (node.id == 13));
/*     */     
/* 425 */     if (node.jjtGetNumChildren() == 0) {
/* 426 */       Token token = node.jjtGetFirstToken();
/* 427 */       return createQuery(field, token, toString(node));
/*     */     }
/* 429 */     List<Query> sub = new LinkedList();
/* 430 */     ConjQuery conj = null;
/* 431 */     Query.Modifier mod = null;
/* 432 */     for (int i = 0; i < node.jjtGetNumChildren(); i++) {
/* 433 */       SimpleNode child = (SimpleNode)node.jjtGetChild(i);
/* 434 */       switch (child.id) {
/*     */       case 9: 
/* 436 */         mod = toModifier(child);
/* 437 */         break;
/*     */       case 8: 
/* 439 */         conj = toConjunction(child);
/* 440 */         break;
/*     */       case 12: 
/*     */       case 13: 
/*     */       case 14: 
/* 444 */         if (!sub.isEmpty()) {
/* 445 */           if (conj == null) {
/* 446 */             sub.add(new ConjQuery(ConjQuery.Conjunction.AND));
/*     */           } else {
/* 448 */             sub.add(conj);
/* 449 */             conj = null;
/*     */           }
/*     */         }
/* 452 */         Query term = toTerm(field, child);
/* 453 */         if (mod != null) {
/* 454 */           term.setModifier(mod);
/* 455 */           mod = null;
/*     */         }
/* 457 */         sub.add(term);
/* 458 */         break;
/*     */       case 10: case 11: default: 
/* 460 */         if (!$assertionsDisabled) throw new AssertionError();
/*     */         break; }
/*     */     }
/* 463 */     return new SubQuery(sub);
/*     */   }
/*     */   
/*     */   private String toString(SimpleNode node)
/*     */   {
/* 468 */     assert (node.jjtGetNumChildren() == 0);
/*     */     
/* 470 */     switch (node.id) {
/*     */     case 3: 
/*     */     case 12: 
/*     */     case 13: 
/* 474 */       return toString(node.jjtGetFirstToken());
/*     */     case 14: 
/* 476 */       Token token = node.jjtGetFirstToken();
/* 477 */       switch (token.kind) {
/*     */       case 8: 
/*     */       case 9: 
/* 480 */         return token.image + toString(token.next);
/*     */       }
/* 482 */       return toString(token);
/*     */     }
/*     */     
/* 485 */     if (!$assertionsDisabled) throw new AssertionError();
/* 486 */     return "";
/*     */   }
/*     */   
/*     */ 
/*     */   private String toString(Token token)
/*     */   {
/* 492 */     switch (token.kind) {
/*     */     case 10: 
/* 494 */       return token.image;
/*     */     case 13: 
/* 496 */       return token.image.substring(1, token.image.length() - 1).replaceAll("\\\\\"", "\"");
/*     */     case 15: 
/* 498 */       return token.image.substring(1, token.image.length() - 1);
/*     */     }
/* 500 */     if (!$assertionsDisabled) throw new AssertionError();
/* 501 */     return "";
/*     */   }
/*     */   
/*     */   private ConjQuery toConjunction(SimpleNode node)
/*     */   {
/* 506 */     assert (node.id == 8);
/*     */     
/* 508 */     switch (node.jjtGetFirstToken().kind) {
/*     */     case 5: 
/* 510 */       return new ConjQuery(ConjQuery.Conjunction.AND);
/*     */     case 6: 
/* 512 */       return new ConjQuery(ConjQuery.Conjunction.OR);
/*     */     }
/* 514 */     if (!$assertionsDisabled) throw new AssertionError();
/* 515 */     return null;
/*     */   }
/*     */   
/*     */   private Query.Modifier toModifier(SimpleNode node)
/*     */   {
/* 520 */     assert (node.id == 9);
/* 521 */     switch (node.jjtGetFirstToken().kind) {
/*     */     case 8: 
/* 523 */       return Query.Modifier.PLUS;
/*     */     case 7: 
/*     */     case 9: 
/* 526 */       return Query.Modifier.MINUS;
/*     */     }
/* 528 */     return Query.Modifier.NONE;
/*     */   }
/*     */   
/*     */   private void processSortBy(SimpleNode node)
/*     */   {
/* 533 */     assert (node.id == 11);
/* 534 */     this.sortBy = node.jjtGetFirstToken().next.image;
/*     */   }
/*     */   
/*     */   private Query createQuery(Token field, Token term, String text) throws ParseException, ServiceException
/*     */   {
/* 539 */     switch (field.kind) {
/*     */     case 67: 
/* 541 */       if (text.equalsIgnoreCase("attachment")) {
/* 542 */         return AttachmentQuery.createQuery("any");
/*     */       }
/* 544 */       return new HasQuery(text);
/*     */     
/*     */     case 69: 
/* 547 */       return AttachmentQuery.createQuery(text);
/*     */     case 68: 
/* 549 */       return TypeQuery.createQuery(text);
/*     */     case 70: 
/* 551 */       return ItemQuery.create(this.mailbox, text);
/*     */     case 65: 
/*     */     case 66: 
/* 554 */       ItemId iid = null;
/* 555 */       int subfolderSplit = text.indexOf('/');
/*     */       
/* 557 */       String subfolderPath = null;
/* 558 */       String iidStr; if (subfolderSplit > 0) {
/* 559 */         String iidStr = text.substring(0, subfolderSplit);
/* 560 */         subfolderPath = text.substring(subfolderSplit + 1);
/*     */       } else {
/* 562 */         iidStr = text;
/*     */       }
/* 564 */       iid = new ItemId(iidStr, (String)null);
/*     */       try {
/* 566 */         return InQuery.create(this.mailbox, iid, subfolderPath, field.kind == 66);
/*     */       }
/*     */       catch (ServiceException e) {
/* 569 */         ZimbraLog.index.debug("Ignoring INID/UNDERID clause b/c of ServiceException", e);
/* 570 */         return InQuery.create(InQuery.In.NONE, false);
/*     */       }
/*     */     
/*     */     case 29: 
/*     */     case 30: 
/* 575 */       Integer folderId = (Integer)FOLDER2ID.get(text.toLowerCase());
/* 576 */       if (folderId != null) {
/* 577 */         return InQuery.create(this.mailbox, folderId.intValue(), field.kind == 30);
/*     */       }
/* 579 */       return InQuery.create(this.mailbox, text, field.kind == 30);
/*     */     
/*     */ 
/*     */     case 32: 
/* 583 */       return new TagQuery(text, true);
/*     */     case 63: 
/*     */       try {
/* 586 */         return new PriorityQuery(PriorityQuery.Priority.valueOf(text.toUpperCase()));
/*     */       } catch (IllegalArgumentException e) {
/* 588 */         throw exception("INVALID_PRIORITY", term);
/*     */       }
/*     */     case 64: 
/*     */       try {
/* 592 */         return BuiltInQuery.getQuery(text.toLowerCase(), this.mailbox, this.analyzer);
/*     */       } catch (IllegalArgumentException e) {
/* 594 */         throw exception("UNKNOWN_TEXT_AFTER_IS", term);
/*     */       }
/*     */     case 58: 
/* 597 */       return ConvQuery.create(this.mailbox, text);
/*     */     case 59: 
/* 599 */       return ConvCountQuery.create(text);
/*     */     case 43: 
/* 601 */       return createDateQuery(DateQuery.Type.DATE, term, text);
/*     */     case 44: 
/* 603 */       return createDateQuery(DateQuery.Type.MDATE, term, text);
/*     */     case 45: 
/* 605 */       return createDateQuery(DateQuery.Type.DAY, term, text);
/*     */     case 46: 
/* 607 */       return createDateQuery(DateQuery.Type.WEEK, term, text);
/*     */     case 47: 
/* 609 */       return createDateQuery(DateQuery.Type.MONTH, term, text);
/*     */     case 48: 
/* 611 */       return createDateQuery(DateQuery.Type.YEAR, term, text);
/*     */     case 49: 
/* 613 */       return createDateQuery(DateQuery.Type.AFTER, term, text);
/*     */     case 50: 
/* 615 */       return createDateQuery(DateQuery.Type.BEFORE, term, text);
/*     */     case 53: 
/* 617 */       return createDateQuery(DateQuery.Type.CONV_START, term, text);
/*     */     case 54: 
/* 619 */       return createDateQuery(DateQuery.Type.CONV_END, term, text);
/*     */     case 51: 
/* 621 */       return createDateQuery(DateQuery.Type.APPT_START, term, text);
/*     */     case 52: 
/* 623 */       return createDateQuery(DateQuery.Type.APPT_END, term, text);
/*     */     case 25: 
/* 625 */       if (Strings.isNullOrEmpty(text)) {
/* 626 */         throw exception("MISSING_TEXT_AFTER_TOFROM", term);
/*     */       }
/* 628 */       return AddrQuery.create(this.analyzer, EnumSet.of(AddrQuery.Address.TO, AddrQuery.Address.FROM), text);
/*     */     case 26: 
/* 630 */       if (Strings.isNullOrEmpty(text)) {
/* 631 */         throw exception("MISSING_TEXT_AFTER_TOCC", term);
/*     */       }
/* 633 */       return AddrQuery.create(this.analyzer, EnumSet.of(AddrQuery.Address.TO, AddrQuery.Address.CC), text);
/*     */     case 27: 
/* 635 */       if (Strings.isNullOrEmpty(text)) {
/* 636 */         throw exception("MISSING_TEXT_AFTER_FROMCC", term);
/*     */       }
/* 638 */       return AddrQuery.create(this.analyzer, EnumSet.of(AddrQuery.Address.FROM, AddrQuery.Address.CC), text);
/*     */     case 28: 
/* 640 */       if (Strings.isNullOrEmpty(text)) {
/* 641 */         throw exception("MISSING_TEXT_AFTER_TOFROMCC", term);
/*     */       }
/* 643 */       return AddrQuery.create(this.analyzer, EnumSet.of(AddrQuery.Address.TO, AddrQuery.Address.FROM, AddrQuery.Address.CC), text);
/*     */     case 23: 
/* 645 */       if (Strings.isNullOrEmpty(text)) {
/* 646 */         throw exception("MISSING_TEXT_AFTER_FROM", term);
/*     */       }
/* 648 */       return SenderQuery.create(this.analyzer, text);
/*     */     case 22: 
/* 650 */       if (Strings.isNullOrEmpty(text)) {
/* 651 */         throw exception("MISSING_TEXT_AFTER_TO", term);
/*     */       }
/* 653 */       return createAddrDomainQuery("to", text);
/*     */     case 24: 
/* 655 */       if (Strings.isNullOrEmpty(text)) {
/* 656 */         throw exception("MISSING_TEXT_AFTER_CC", term);
/*     */       }
/* 658 */       return createAddrDomainQuery("cc", text);
/*     */     case 19: 
/* 660 */       if (Strings.isNullOrEmpty(text)) {
/* 661 */         throw exception("MISSING_TEXT_AFTER_ENVTO", term);
/*     */       }
/* 663 */       return createAddrDomainQuery("env_to", text);
/*     */     case 20: 
/* 665 */       if (Strings.isNullOrEmpty(text)) {
/* 666 */         throw exception("MISSING_TEXT_AFTER_ENVFROM", term);
/*     */       }
/* 668 */       return createAddrDomainQuery("env_from", text);
/*     */     case 62: 
/* 670 */       return new ModseqQuery(text);
/*     */     case 55: 
/* 672 */       return createSizeQuery(SizeQuery.Type.EQ, term, text);
/*     */     case 56: 
/* 674 */       return createSizeQuery(SizeQuery.Type.GT, term, text);
/*     */     case 57: 
/* 676 */       return createSizeQuery(SizeQuery.Type.LT, term, text);
/*     */     case 17: 
/* 678 */       return SubjectQuery.create(this.analyzer, text);
/*     */     case 40: 
/* 680 */       return createFieldQuery(field.image, term, text);
/*     */     case 21: 
/* 682 */       return new ContactQuery(text);
/*     */     case 16: 
/* 684 */       if (this.types.contains(MailItem.Type.CONTACT)) {
/* 685 */         List<Query> clauses = new ArrayList(3);
/* 686 */         clauses.add(new ContactQuery(text));
/* 687 */         clauses.add(new ConjQuery(ConjQuery.Conjunction.OR));
/* 688 */         clauses.add(createContentQuery(text));
/* 689 */         return new SubQuery(clauses);
/*     */       }
/* 691 */       return createContentQuery(text);
/*     */     }
/*     */     
/* 694 */     return new TextQuery(this.analyzer, (String)JJ2LUCENE.get(Integer.valueOf(field.kind)), text);
/*     */   }
/*     */   
/*     */   private SizeQuery createSizeQuery(SizeQuery.Type type, Token term, String text) throws ParseException
/*     */   {
/*     */     try {
/* 700 */       return new SizeQuery(type, text);
/*     */     } catch (java.text.ParseException e) {
/* 702 */       throw exception("INVALID_SIZE", term);
/*     */     }
/*     */   }
/*     */   
/*     */   private DateQuery createDateQuery(DateQuery.Type type, Token term, String text) throws ParseException {
/* 707 */     DateQuery query = new DateQuery(type);
/*     */     try {
/* 709 */       query.parseDate(text, this.timezone, this.locale);
/*     */     } catch (java.text.ParseException e) {
/* 711 */       throw exception("INVALID_DATE", term);
/*     */     }
/* 713 */     return query;
/*     */   }
/*     */   
/*     */   private Query createAddrDomainQuery(String field, String term) {
/* 717 */     if (term.startsWith("@")) {
/* 718 */       return new DomainQuery(field, term);
/*     */     }
/* 720 */     return new TextQuery(this.analyzer, field, term);
/*     */   }
/*     */   
/*     */   private Query createFieldQuery(String field, Token term, String text) throws ServiceException, ParseException
/*     */   {
/* 725 */     Matcher matcher = FIELD_REGEX.matcher(field);
/* 726 */     if (matcher.matches()) {
/* 727 */       String name = (String)Objects.firstNonNull(matcher.group(1), matcher.group(2));
/* 728 */       return FieldQuery.create(this.mailbox, name, text);
/*     */     }
/* 730 */     throw exception("INVALID_FIELD_FORMAT", term);
/*     */   }
/*     */   
/*     */   private Query createContentQuery(String text)
/*     */   {
/* 735 */     return new TextQuery(this.analyzer, "l.content", text);
/*     */   }
/*     */   
/*     */   private Query createQuickQuery(String text) {
/* 739 */     if ((this.types.size() == 1) && (this.types.contains(MailItem.Type.CONTACT))) {
/* 740 */       return new ContactQuery(text);
/*     */     }
/* 742 */     TextQuery query = new TextQuery(this.analyzer, "l.content", text);
/* 743 */     query.setQuick(true);
/* 744 */     return query;
/*     */   }
/*     */   
/*     */   private ParseException exception(String message, Token token)
/*     */   {
/* 749 */     ParseException e = new ParseException(message);
/* 750 */     e.currentToken = token;
/* 751 */     return e;
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/index/query/parser/QueryParser.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */